﻿//-----------------------------------------------------------------------
// <copyright file="Open.cs" company="FCIS">
//     Company copyright tag.
// </copyright>
//-----------------------------------------------------------------------

namespace IPPackage.ImageOperation
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using IPPackage;

    /// <summary>
    /// the class has functions of open image by Multi ways
    /// </summary>
    public class Open : Operation
    {
        /// <summary>
        /// the image in bitmap
        /// </summary>
        private Bitmap myImg;

        /// <summary>
        /// make image gray.
        /// </summary>
        /// <returns>the new image</returns>
        public Bitmap GrayImg()
        {
            Bitmap img;
            try
            {
                Color[,] newBuffer = new Color[BufferOfImage.GetLength(0), BufferOfImage.GetLength(1)];
                img = new Bitmap(BufferOfImage.GetLength(0), BufferOfImage.GetLength(1));
                int newRed, newGreen, newBlue;
                for (int i = 0; i < BufferOfImage.GetLength(1); i++)
                {
                    for (int j = 0; j < BufferOfImage.GetLength(0); j++)
                    {
                        newRed = (BufferOfImage[j, i].R + BufferOfImage[j, i].G + BufferOfImage[j, i].B) / 3;
                        newGreen = (BufferOfImage[j, i].R + BufferOfImage[j, i].G + BufferOfImage[j, i].B) / 3;
                        newBlue = (BufferOfImage[j, i].R + BufferOfImage[j, i].G + BufferOfImage[j, i].B) / 3;
                        newBuffer[j, i] = Color.FromArgb(newRed, newGreen, newBlue);
                        img.SetPixel(j, i, newBuffer[j, i]);
                    }
                }

                this.NewBufferOfImage = newBuffer;
            }
            catch (Exception ex)
            {
                img = null;
                Logger.LogException(ex);
            }

            return img;
        }

        /// <summary>
        /// Open the image for any type.
        /// </summary>
        /// <param name="path">The path of image.</param>
        /// <returns>the bitmap of image</returns>
        public Bitmap OpenImage(string path)
        {
            string[] fileFormat = path.Split('.');
            if (fileFormat[1] == "PPM" || fileFormat[1] == "ppm")
            {
                this.OpenPPMI(path);
            }
            else
            {
                this.OpenImageC(path);
            }

            return this.myImg;
        }

        /// <summary>
        /// Open the image for common types.
        /// </summary>
        /// <param name="path">The path of image would open.</param>
        public void OpenImageC(string path)
        {
            try
            {
                this.myImg = new Bitmap(path);
                BufferOfImage = new Color[this.myImg.Width, this.myImg.Height];
                for (int i = 0; i < this.myImg.Width; i++)
                {
                    for (int j = 0; j < this.myImg.Height; j++)
                    {
                        BufferOfImage[i, j] = this.myImg.GetPixel(i, j);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
            }
        }

        /// <summary>
        /// Saves the image in specified path.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>the flag to sure the image save</returns>
        public bool Save(string path)
        {
            try
            {
                this.myImg.Save(path + ".bmp");
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                return false;
            }
        }

        /// <summary>
        /// Open the PPM image of type p3 or p6.
        /// </summary>
        /// <param name="path">The path of image.</param>
        public void OpenPPMI(string path)
        {
            FileStream img = new FileStream(path, FileMode.Open);
            StreamReader readImg = new StreamReader(img);
            try
            {
                string s = readImg.ReadLine();
                string commentOrN = readImg.ReadLine();
                if (commentOrN[0] == '#')
                {
                    commentOrN = readImg.ReadLine();
                }

                string[] weidthAndHeigth;
                weidthAndHeigth = commentOrN.Split(' ');
                int weidth = int.Parse(weidthAndHeigth[0]);
                int heigth = int.Parse(weidthAndHeigth[1]);
                this.myImg = new Bitmap(weidth, heigth);
                BufferOfImage = new Color[weidth, heigth];
                if (s == "p3" || s == "P3")
                {
                    this.OpenP3Img(readImg);
                }
                else if (s == "p6" || s == "P6")
                {
                    img.Close();
                    FileStream img2 = new FileStream(path, FileMode.Open);
                    this.OpenP6Img(img2);
                    img2.Close();
                }

                readImg.Close();
                img.Close();
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
            }
        }

        /// <summary>
        /// Opens the p3 image.
        /// </summary>
        /// <param name="readImg">The file reader of image.</param>
        private void OpenP3Img(StreamReader readImg)
        {
            char[] seperate = { ' ', '\n' };
            string[] pixels;
            readImg.ReadLine();
            pixels = readImg.ReadToEnd().Split(seperate, StringSplitOptions.RemoveEmptyEntries);
            int len = 0;
            for (int j = 0; j < BufferOfImage.GetLength(1); j++)
            {
                for (int i = 0; i < BufferOfImage.GetLength(0); i++)
                {
                    try
                    {
                        BufferOfImage[i, j] = Color.FromArgb(int.Parse(pixels[len]), int.Parse(pixels[len + 1]), int.Parse(pixels[len + 2]));
                        this.myImg.SetPixel(i, j, BufferOfImage[i, j]);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogException(ex);
                    }

                    len += 3;
                }
            }
        }

        /// <summary>
        /// Opens the p6 img.
        /// </summary>
        /// <param name="readImg">The read img.</param>
        private void OpenP6Img(FileStream readImg)
        {
            byte[] pxl = new byte[readImg.Length];
            readImg.Read(pxl, 0, pxl.Length);
            int len = pxl.Length - (BufferOfImage.GetLength(1) * BufferOfImage.GetLength(0) * 3);
            for (int j = 0; j < BufferOfImage.GetLength(1); j++)
            {
                for (int i = 0; i < BufferOfImage.GetLength(0); i++)
                {
                    try
                    {
                        BufferOfImage[i, j] = Color.FromArgb(pxl[len], pxl[len + 1], pxl[len + 2]);
                        this.myImg.SetPixel(i, j, BufferOfImage[i, j]);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogException(ex);
                    }

                    len += 3;
                }
            }
        }
    }
}
